//
//  LELAnyCodable.swift
//  FingerABC
//
//  Created by liyahao on 2025/7/7.
//

import UIKit

// MARK: - LELAnyCodable 辅助类型
struct LELAnyCodable: Codable {
    let value: Any
    
    init<T>(_ value: T?) {
        self.value = value ?? ()
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        
        if let intValue = try? container.decode(Int.self) {
            value = intValue
        } else if let doubleValue = try? container.decode(Double.self) {
            value = doubleValue
        } else if let stringValue = try? container.decode(String.self) {
            value = stringValue
        } else if let stringValue = try? container.decode(UInt64.self) {
            value = stringValue
        } else if let boolValue = try? container.decode(Bool.self) {
            value = boolValue
        } else if let arrayValue = try? container.decode([LELAnyCodable].self) {
            value = arrayValue.map { $0.value }
        } else if let dictValue = try? container.decode([String: LELAnyCodable].self) {
            value = dictValue.mapValues { $0.value }
        } else {
            throw DecodingError.dataCorrupted(
                DecodingError.Context(codingPath: decoder.codingPath,
                                    debugDescription: "Cannot decode value")
            )
        }
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        
        switch value {
        case let intValue as Int:
            try container.encode(intValue)
        case let doubleValue as Double:
            try container.encode(doubleValue)
        case let stringValue as String:
            try container.encode(stringValue)
        case let boolValue as Bool:
            try container.encode(boolValue)
        case let int64Value as UInt64:
            try container.encode(int64Value)
        case let arrayValue as [Any]:
            try container.encode(arrayValue.map { LELAnyCodable($0) })
        case let dictValue as [String: Any]:
            try container.encode(dictValue.mapValues { LELAnyCodable($0) })
        default:
            try container.encodeNil()
        }
    }
}
